#!/Users/mabo/opt/anaconda3/bin/python
# -*- coding: utf-8 -*-
# 检查bib各种信息
import sys
import os
import bibtexparser
import glob
import re
import numpy as np
import copy
import pandas as pd
import matplotlib
import matplotlib.pyplot as plt
import scifig.figure as scifig
import time
import datetime
from colored import fg, bg, attr

C_GREEN = fg("green")
C_RED = fg("red")
C_BLUE = fg("blue")
C_DEFAULT = attr("reset")
# ----------------------------------
'''
chapter_path = '/Users/mabo/Nutstore Files/Nutstore/6 Writing/Latex writing/LiteratureNotes/Chapters'
bib_path = '/Users/mabo/Nutstore Files/Nutstore/6 Writing/'
with open(os.path.join(os.getcwd(),'filename.txt'), 'w') as outfile:
    for filename in glob.glob(os.path.join(chapter_path,'*.tex')):
        with open(filename) as infile:
            for line in infile:
                outfile.write(line+"\n")
filename_bib = os.path.join(bib_path,'Bibliography.bib')
filename_tex = 'filename.txt'
'''
# ----------------------------------
keys_check_article = ["title","journal","author","year","volume","number","pages"]
keys_check_book=['title','year','author','publisher','address','series','volume']
keys_check_incollection=['title','booktitle','year','pages','author','publisher','address','series','volume']
# ----------------------------------
def loadrefs(filename_bib):
    with open(filename_bib) as bibtex_file:
        bib_database = bibtexparser.load(bibtex_file)
    entries = bib_database.entries
    return entries

def infoRefs(refs):
    print("总共%d个参考 文献\n" % (len(refs)))
    reftypes = []
    for ref in refs:
        reftypes.append(ref["ENTRYTYPE"])
    reftypes = np.array(reftypes)
    reftypes_unique = np.unique(reftypes)
    print("总共%d个文献类型，分别为: " % (len(reftypes_unique)))
    for reftype in reftypes_unique:
        print("%s; " % (reftype))
    print("\n")
    for reftype in reftypes_unique:
        if reftype != "article":
            print("%s(%d)\n" % (reftype, len(reftypes[reftypes == reftype])))
            for ref in refs:
                if ref["ENTRYTYPE"] == reftype:
                    print("\t" + ref["ID"] + "\n")
    print("\n\n")

def check_article(refs, keys_check, reftype, fpout):
    print("检查article的信息\n")
    for key in keys_check:
        print("\t" + key + "\n")
        num_wrong = 0
        for ref in refs:
            if ref["ENTRYTYPE"] != reftype:
                continue
            if key in ref:
                if ref[key] == []:
                    print("\t\t" + key + " in " + ref + " is  empty\n")
                    num_wrong = num_wrong + 1
            else:
                print("\t\t" + ref["ID"] + "\n")
                num_wrong = num_wrong + 1
        if num_wrong == 0:
            print("\t\t完整")
            print("\n")

def checkrefs(filename_bib):
    # 1. refs
    refs = loadrefs(filename_bib)
    # 2. num of refs
    num_refs = len(refs)
    # basic information
    infoRefs(refs)
    # 3 check keys for article
    check_article(refs, keys_check_article, "article", fpout)
           

def check_tex_authors(filename_tex):
    with open (filename_tex,'r') as file:
        lines_tex = file.read()
        matches = re.findall(r"(\w*)\\citep{([\w,]+)}", lines_tex)
        df = pd.DataFrame(matches)
        df.columns = ['ID','authors']
        df = df.authors.apply(lambda x: pd.value_counts(x.split(","))).sum(axis = 0)
        df = pd.DataFrame([df]).T
        df['author'] = df.index
        df.reset_index(drop=True, inplace=True)
        df.columns = ['counter','author']
        df = df[['author','counter']]
        author_tex = df.sort_values(by='counter',ascending=False)
        return author_tex

def check_bib_authors(filename_bib):
    with open (filename_bib,'r') as file:
        lines_bib = file.read()
        matches = re.findall(r"@article{[\w,]+", lines_bib)
        #print(matches)
        data =[]
        for i in matches:
            raw_data = re.split(r'[{,]',i)[1]
            data.append(raw_data)
        return data

def plot_tex_authors(filename_tex):
    df = check_tex_authors(filename_tex)
    df = df.nlargest(30, 'counter')
    fig, axs = plt.subplots(
        1,
        1,
        sharex=False,
        sharey=False,
        gridspec_kw={"width_ratios": [1], "height_ratios": [1]},
        figsize=scifig.figsize("full", ratio="1.5:1"),
    )
    ax = axs
    author_first_favor = df['author']
    fullname_author_first_favor=copy.deepcopy(author_first_favor)
    y = df['counter']
    x = np.arange(0,len(author_first_favor))
    barwidth=0.7
    ax.bar(x,y,barwidth)
    ax.xaxis.set_ticks(x)
    authors=[]
    for author0 in fullname_author_first_favor:
        authors.append(author0.split(',')[0])
    authors=np.array(authors)
    ax.xaxis.set_ticklabels(authors,rotation=90)
    ax.set_ylim(np.min(y)-barwidth,np.max(y)+barwidth)
    ax.set_ylabel('Number of cited references')
    ax.set_xlim(np.max(x)+barwidth,np.min(x)-barwidth)
    ax.grid(alpha=0.1)
    ax.set_title('Most cited authors')
    plt.tight_layout()
    # save fig
    filename_fig = "tex_authors"
    plt.savefig(filename_fig + ".pdf")
    plt.savefig(filename_fig + ".png", dpi=400, transparent=1)

def plot_types(refs):
    reftypes = []
    for ref in refs:
        reftypes.append(ref["ENTRYTYPE"])
    reftypes = np.array(reftypes)
    reftypes_unique = np.unique(reftypes)
    num_types = []
    label_types = []
    num_articles = 0
    for i in range(0, len(reftypes_unique)):
        reftype = reftypes_unique[i]
        if reftype == "article":
            num_articles = len(reftypes[reftypes == reftype])
        else:
            num_types.append(len(reftypes[reftypes == reftype]))
            label_types.append(reftype)
    num_types = np.array(num_types, dtype=int)

    fig, axs = plt.subplots(
        1,
        2,
        sharex=False,
        sharey=False,
        gridspec_kw={"width_ratios": [1, 0.7], "height_ratios": [1]},
        figsize=scifig.figsize("full", ratio="2.35:1"),
    )
    ax_pie = axs[0]
    ax_legend = axs[1]
    ax_pie.axis("off")
    ax_legend.axis("off")

    def func(pct, allvals, absolute0=[], fmt_pct=".1f"):
        absolute = int(pct / 100.0 * np.sum(allvals))
        if absolute0 != []:
            pct = absolute / (np.sum(allvals) + absolute0) * 100
        return ("{:" + fmt_pct + "}%\n({:d})").format(pct, absolute)

    size_ouoter = 0.8
    size_inner = 0.3
    radius = 1.75
    colors_noarticle = []
    for i in range(0, len(num_types)):
        colors_noarticle.append(scifig.colors(i))
    wedges1, texts, autotexts = ax_pie.pie(
        num_types,
        radius=radius,
        autopct=lambda pct: func(pct, num_types, absolute0=num_articles),
        colors=colors_noarticle,
        textprops=dict(color="k", fontsize=9),
        wedgeprops=dict(width=size_ouoter, edgecolor="gray"),
        pctdistance=0.85,
        rotatelabels=False,
    )
    l1 = ax_legend.legend(
        wedges1,
        label_types,
        loc="upper left",
        ncol=1,
        shadow=True,
        labelspacing=0.5,
        bbox_to_anchor=(-0.3, 0.1, 1, 1),
        title="Non-article",
    )
    ax_legend.add_artist(l1)
    num_types2 = np.array([num_articles, np.sum(num_types)])
    wedges2, texts, autotexts = ax_pie.pie(
        num_types2,
        radius=radius - size_ouoter,
        autopct=lambda pct: func(pct, num_types2),
        colors=[
            scifig.colors(len(reftypes_unique) - 1),
            scifig.colors(len(reftypes_unique)),
        ],
        textprops=dict(color="w", fontsize=9),
        wedgeprops=dict(width=radius - size_ouoter - size_inner, edgecolor="gray"),
        pctdistance=0.7,
        rotatelabels=False,
    )
    l2 = ax_legend.legend(
        wedges2,
        ["Article", "Non-article"],
        loc="lower left",
        ncol=1,
        shadow=True,
        labelspacing=0.5,
        bbox_to_anchor=(-0.3, -0.2, 1, 1),
        title="ENTRYTYPE",
    )

    ax_pie.text(0, 0, np.sum(num_types) + num_articles, va="center", ha="center")

    plt.subplots_adjust(left=0.1, right=1, top=0.85, bottom=0.15)
    # save fig
    filename_fig = "types"
    plt.savefig(filename_fig + ".pdf")
    plt.savefig(filename_fig + ".png", dpi=400, transparent=1)
    # plt.show()

def plot_journal(refs):
    journals = []
    for ref in refs:
        if "journal" in ref:
            journals.append(ref["journal"])
    journals = np.array(journals)
    journals_unique = np.unique(journals)
    journal_favor = []
    num_journal_favor = []
    journal_others=[]
    num_journal_others=[]
    for journal in journals_unique:
        num_journal = len(journals[journals == journal])
        # if ((num_journal > 1) & (len(journal) < 60)):
        if ((num_journal > 2) & (len(journal) < 60)):
            journal_favor.append(journal)
            num_journal_favor.append(num_journal)
        else:
            journal_others.append(journal)
            num_journal_others.append(num_journal)
            # print(journal,num_journal)
    journal_favor.append('Others')
    num_journal_favor.append(len(refs)-np.sum(num_journal_favor))
    num_journal_favor = np.array(num_journal_favor, dtype=int)
    journal_favor=np.array(journal_favor,dtype=str)
    ind = np.argsort(num_journal_favor)
    num_journal_favor=num_journal_favor[ind]
    journal_favor=journal_favor[ind]
    for journal_o,num_journal_o in zip(journal_others,num_journal_others):
        print(journal_o,num_journal_o)
    print('num of other journal: ',len(journal_others), 'num of refs_others: ',np.sum(num_journal_others))
    # print('num of favorite journal: ',len(journal_favor), 'num of favorite refs: ',np.sum(num_journal_favor))
    for i in range(0,len(journal_favor)):
        if(journal_favor[i]=='Journal of Geophysical Research: Solid Earth'):
                journal_favor[i]='JGR: Solid Earth'
        if(journal_favor[i]=='Earth and Planetary Science Letters'):
            journal_favor[i]='EPSL'
        if(journal_favor[i]=='Geochemistry, Geophysics, Geosystems'):
            journal_favor[i]='G3'
        if(journal_favor[i]=='Geophysical Research Letters'):
            journal_favor[i]='GRL'
        if(journal_favor[i]=='Geochimica et Cosmochimica Acta'):
            journal_favor[i]='GCA'
        if(journal_favor[i]=='Geophysical Journal International'):
            journal_favor[i]='GJI'
        if(journal_favor[i]=='Annual Review of Earth and Planetary Sciences'):
            journal_favor[i]='AREPS'
        if(journal_favor[i]=='Journal of Geophysical Research'):
            journal_favor[i]='JGR'
        if(journal_favor[i]=='American Journal of Science'):
            journal_favor[i]='AJS'
        if(journal_favor[i]=='Reviews of Geophysics'):
            journal_favor[i]='RG'
    # plot
    fig, axs = plt.subplots(
        1,
        1,
        sharex=False,
        sharey=False,
        gridspec_kw={"width_ratios": [1], "height_ratios": [1]},
        figsize=scifig.figsize("full",ratio='1.5:1'),
    )
    ax = axs
    y = num_journal_favor
    x = np.arange(0,len(num_journal_favor))
    barwidth=0.7
    ax.bar(x,y,barwidth)
    ax.xaxis.set_ticks(x)
    ax.xaxis.set_ticklabels(journal_favor,rotation=90)
    ax.set_ylim(np.min(y)-barwidth,np.max(y)+barwidth)
    ax.set_xlim(np.max(x)+barwidth,np.min(x)-barwidth)
    ax.set_ylabel('Number of cited references')
    ax.set_title('Journals of cited references')
    ax.grid(alpha=0.1)
    plt.tight_layout()
    # save fig
    filename_fig = "journals"
    plt.savefig(filename_fig + ".pdf")
    plt.savefig(filename_fig + ".png", dpi=400, transparent=1)

def plot_years(refs):
    years = []
    for ref in refs:
        if "year" in ref:
            years.append(ref["year"])
    years = np.array(years)
    years_unique = np.unique(years)
    num_years=[]
    for year in years_unique:
        num_year=len(years[years==year])
        num_years.append(num_year)
    num_years=np.array(num_years,dtype=int)
    years_unique=np.array(years_unique,dtype=int)
    # plot
    fig, axs = plt.subplots(
        1,
        1,
        sharex=False,
        sharey=False,
        gridspec_kw={"width_ratios": [1], "height_ratios": [1]},
        figsize=scifig.figsize("full", ratio="1:1.5"),
    )
    ax = axs
    x = num_years
    y = years_unique-np.min(years_unique)
    barwidth=0.7
    ax.barh(y,x,barwidth)
    ax.yaxis.set_ticks(y)
    ax.yaxis.set_ticklabels(years_unique)
    ax.set_ylim(np.min(y)-barwidth,np.max(y)+barwidth)
    ax.set_xlabel('Number of cited references')
    ax.grid(alpha=0.1)
    ax.set_title('Years of cited references')
    plt.tight_layout()
    # save fig
    filename_fig = "years"
    plt.savefig(filename_fig + ".pdf")
    plt.savefig(filename_fig + ".png", dpi=400, transparent=1)

def plot_authors(refs):
    author_first = []
    for ref in refs:
        if "author" in ref:
            author_first.append(ref["author"].split(',')[0])
    author_first = np.array(author_first)
    author_first_unique = np.unique(author_first)
    num_author_first=[]
    for author in author_first_unique:
        num_author=len(author_first[author_first==author])
        num_author_first.append(num_author)
    num_author_first=np.array(num_author_first,dtype=int)
    author_first_unique=np.array(author_first_unique,dtype=str)
    ind=np.argsort(num_author_first)
    author_first_unique=author_first_unique[ind]
    num_author_first=num_author_first[ind]
    # print(len(author_first_unique))
    # for author,num in zip(author_first_unique,num_author_first):
    #     print(author,num)
    ind_favor=(num_author_first>2)
    num_author_first_favor=num_author_first[ind_favor]
    author_first_favor=author_first_unique[ind_favor]
    # get full name of most cited first authors
    fullname_author_first_favor=copy.deepcopy(author_first_favor)
    for i in range(0,len(author_first_favor)):
        firstauthor=author_first_favor[i]
        for ref in refs:
            if "author" in ref:
                familyname_firstauthor=ref["author"].split(',')[0]
                if(familyname_firstauthor==firstauthor):
                    fullname_author_first_favor[i]=ref["author"].split('and')[0]
                    continue
    # for a,b in zip(author_first_favor,fullname_author_first_favor):
    #     print(a,b)
    # plot
    fig, axs = plt.subplots(
        1,
        1,
        sharex=False,
        sharey=False,
        gridspec_kw={"width_ratios": [1], "height_ratios": [1]},
        figsize=scifig.figsize("full", ratio="1.5:1"),
    )
    ax = axs
    y = num_author_first_favor
    x = np.arange(0,len(author_first_favor))
    barwidth=0.7
    ax.bar(x,y,barwidth)
    ax.xaxis.set_ticks(x)
    authors=[]
    for author0 in fullname_author_first_favor:
        authors.append(author0.split(',')[0])
    authors=np.array(authors)
    ax.xaxis.set_ticklabels(authors,rotation=90)
    ax.set_ylim(np.min(y)-barwidth,np.max(y)+barwidth)
    ax.set_ylabel('Number of cited references')
    ax.set_xlim(np.max(x)+barwidth,np.min(x)-barwidth)
    ax.grid(alpha=0.1)
    ax.set_title('Most cited authors')
    plt.tight_layout()
    # save fig
    filename_fig = "authors"
    plt.savefig(filename_fig + ".pdf")
    plt.savefig(filename_fig + ".png", dpi=400, transparent=1)

def plot_all(filename_bib):
    refs = loadrefs(filename_bib)
    # 1. plot types
    plot_types(refs)
    # 2. journals
    plot_journal(refs)
    # 3. years
    plot_years(refs)
    # 4. authors
    plot_authors(refs)
    # 5. tex author citation time
    plot_tex_authors(filename_tex)

# ----------------------------------
def TimeStampToTime(timestamp):
    '''把时间戳转化为时间: 1479264792 to 2016-11-16 10:53:12'''
    timeStruct = time.localtime(timestamp)
    return time.strftime('%Y-%m-%d %H:%M:%S',timeStruct)
def get_FileSize(filePath):
    '''获取文件的大小,结果保留两位小数，单位为MB'''
    fsize = os.path.getsize(filePath)
    fsize = fsize/float(1024*1024)
    return round(fsize,2)
def get_FileAccessTime(filePath):
    '''获取文件的访问时间'''
    t = os.path.getatime(filePath)
    return TimeStampToTime(t)
def get_FileCreateTime(filePath):
    '''获取文件的创建时间'''
    t = os.path.getctime(filePath)
    return TimeStampToTime(t)
def get_FileModifyTime(filePath):
    '''获取文件的修改时间'''
    t = os.path.getmtime(filePath)
    return TimeStampToTime(t)
def usage(argv):
    basename = argv[0]
    print("======================" + basename + "=======================")
    print("检查latex中文献和bib中文献的各种情况并作图")
    print("BMA",get_FileCreateTime(os.path.join(os.getcwd(),'literature_statistics_withpath.py')),"Kiel",get_FileModifyTime(os.path.join(os.getcwd(),'literature_statistics_withpath.py')))
    print(
        "["
        "Example(plot all figs)"
        " ]: " + C_BLUE + basename + C_RED + " xxx.tex xxx.bib -all" + C_DEFAULT
    )
    print(
        "["
        "Example(plot types of bib)"
        " ]: " + C_BLUE + basename + C_RED + " xxx.tex xxx.bib -type" + C_DEFAULT
    )
    print(
        "["
        "Example(plot author_times of tex)"
        " ]: " + C_BLUE + basename + C_RED + " xxx.tex xxx.bib -tex" + C_DEFAULT
    )
    print(
        "["
        "Example(plot journals of bib)"
        " ]: " + C_BLUE + basename + C_RED + " xxx.tex xxx.bib -journal" + C_DEFAULT
    )
    print(
        "["
        "Example(plot years of bib)"
        " ]: " + C_BLUE + basename + C_RED + " xxx.tex xxx.bib -year" + C_DEFAULT
    )
    print(
        "["
        "Example(plot authors of bib)"
        " ]: " + C_BLUE + basename + C_RED + " xxx.tex xxx.bib -author" + C_DEFAULT
    )
    print("=======================================================")

def main(argv):
    if len(argv) < 3:
        usage(argv)
    else:
        filename_tex = argv[1]
        filename_bib = argv[2]
        refs = loadrefs(filename_bib)
        if argv[3] == "-all":
            plot_all(filename_bib)
        elif argv[3] == "-type":
            plot_types(refs)
        elif argv[3] == "-texcite":
            plot_tex_authors(filename_tex)
        elif argv[3] == "-journal":
            plot_journal(refs)
        elif argv[3] == "-year":
            plot_years(refs)
        elif argv[3] == "-author":
            plot_authors(refs)
        else:
            usage(argv)

if "__main__" == __name__:
    sys.exit(main(sys.argv))